<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<script>
    class BaseLocalStorage {
        constructor(preId, timeSign = '|-|') {
            this.preId = preId;
            this.timeSing = timeSign;
            this.status = {
                SUCCESS: 0,         // 成功
                FAILURE: 1,         // 失败
                OVERFLOW: 2,        // 溢出
                TIMEOUT: 3,         // 过期
            };
            this.storage = localStorage || window.localStorage;
        }

        // 获取本地存储数据库数据真实字段
        getKey(key) {
            return this.preId + key;
        }

        /**
         * 添加或者修改数据
         * @param key           数据字段标识
         * @param value         数据值
         * @param callback      回到函数
         * @param time          添加时间
         */
        set(key, value, callback, time) {
            // 默认操作状态是成功的
            let status = this.status.SUCCESS,
                getKey = this.getKey(key);
            try {
                time = +new Date(time) || time.getTime();
            } catch (e) {
                // 传入的时间参数或者时间参数有无获取默认时间， 一个月
                time = +new Date() + 1000 * 60 * 60 * 24 * 31;
            }

            try {
                this.storage.setItem(getKey, time + this.timeSing + value);
            } catch (e) {
                // 溢出失败， 返回溢出状态
                status = this.status.OVERFLOW;
            }
            callback && callback.call(this, status, getKey, value);
        }

        /**
         * 获取数据
         * @param key           数据字段标识
         * @param callback      回调函数
         * @returns {*}
         */
        get(key, callback) {
            let status = this.status.SUCCESS,
                getKey = this.getKey(key),
                value = null,                   // 默认值为空
                timeSignLen = this.timeSing.length,         // 时间戳与存储数据之间的拼接长度
                index,                  // 时间戳与春出数据之间的拼接符其实位置
                time,                   // 时间戳
                result;                 // 最终获取到的数据
            try {
                value = this.storage.getItem(getKey);
            } catch (e) {
                result = {
                    status: this.status.FAILURE,
                    value: null
                };
                callback && callback.call(this, result.status, result, value);
                return result;
            }

            // 获取成功
            if (value) {
                index = value.indexOf(this.timeSing);
                time = +value.slice(0, index);          // 获取时间戳
                if (+new Date(time) > +new Date() || time === 0) {
                    // 获取数据结果（拼接后面的字符串）
                    value = value.slice(index + timeSignLen);
                } else {
                    // 获取则结果为null
                    value = null;
                    status = this.status.TIMEOUT;
                    time.remove(key);
                }
            } else {
                status = this.status.FAILURE;
            }

            // 设置结果
            result = {
                status: status,
                value: value
            };
            callback && callback.call(this, result.status, result.value);
            return result;
        }

        /**
         * 删除数据
         * @param key           数据字段标识
         * @param callback      回调函数
         */
        remove(key, callback) {
            let status = this.status.FAILURE,
                getKey = this.getKey(key),
                value = null;
            value = this.storage.getItem(getKey);
            if (value) {
                // 删除数据
                this.storage.removeItem(getKey);
                status = this.status.SUCCESS;
            }
            callback && callback.call(this, status, status > 0 ? null : value.slice(value.indexOf(this.timeSing) + this.timeSing.length))
        }
    }


    /*使用实例*/
    let LS = new BaseLocalStorage('LS__');
    LS.set('a', 'xiao ming', function () {
        console.log(arguments)
    });
    LS.get('a', function () {
        console.log(arguments)
    });
    LS.remove('a', function () {
        console.log(arguments)
    });
    LS.remove('a', function () {
        console.log(arguments)
    });
    LS.get('a', function () {
        console.log(arguments)
    });
</script>
</body>
</html>